package top.yohann.study.common.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import top.yohann.study.common.annotion.AuthToken;
import top.yohann.study.common.common.GlobalException;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;

import static top.yohann.study.common.common.ExceptionEnum.AUTH_FAILED;

/**
 * 校验token拦截器
 *
 * @author Yeung Wah
 * @since 2021/5/31
 */
@Configuration
@Slf4j
public class AuthInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Value("${token.name}")
    private String tokenName;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        HandlerMethod method = (HandlerMethod) handler;
        if (!method.getBeanType().isAnnotationPresent(AuthToken.class) && !method.hasMethodAnnotation(AuthToken.class)) {
            return true;
        }

        String commonToken = request.getHeader(tokenName);
        BoundHashOperations<String, String, Object> hashOps = redisTemplate.boundHashOps("common:common_token");
        if (Objects.nonNull(commonToken) && Objects.nonNull(hashOps.get(commonToken))) {
            return true;
        }

        Cookie[] cookies = request.getCookies();
        if (Objects.nonNull(cookies)) {
            for (Cookie cookie : cookies) {
                if (tokenName.equals(cookie.getName())) {
                    commonToken = cookie.getValue();
                    if (Objects.nonNull(hashOps.get(commonToken))) {
                        return true;
                    }
                }
            }
        }

        GlobalException.throwOut(AUTH_FAILED, "请确保密钥正确！");
        return false;
    }

}